﻿using CL_VisionCommu_Test.Helper;
using CLCommuConfig;
using CLVisionCommu.CLCommuTcpIP;
using CLVisionTcpIP;
using ControlzEx.Standard;
using DryIoc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Resources;

namespace TcpIPClient

{
    public class CommuTcpIPClient
    {
        private string ip = "127.0.0.1";
        private int port = 502;

        DateTime dtDisconnect = new DateTime();
        DateTime dtNow = new DateTime();
        public bool NetworkIsOk = false;
        public CLTcpClient tcpClient;
        public JObject rootClass = null;
        string ncOrTs = string.Empty;

        public bool Connected
        {
            get
            {
                return NetworkIsOk;
            }
        }

        public CommuTcpIPClient(string IP, int Port, CommunicationParameters communicationParameters, string ncOrTs)
        {
            ip = IP;
            port = Port;
            this.ncOrTs = ncOrTs;
            NetworkIsOk = Connect(communicationParameters);

        }

        private bool Connect(CommunicationParameters parameters)
        {

            if (tcpClient != null)
                tcpClient.Disconnect();
            tcpClient = new CLTcpClient();
            tcpClient.OnMessageReceived += (msg) =>
            {
                try
                {
                    if (msg.Contains("{") && msg.Contains("}"))
                    {

                        int messageNum = msg.Split('&').Count();
                        string message = msg.Split('&')[messageNum - 2];

                        rootClass = JObject.Parse(message);
                    }
                }
                catch (Exception)
                {

                }


            };
            tcpClient.Connect(out int errorCode, out string errorText, ip, port);
            if (errorCode == -1)
            {
                return false;
            }
            rootClass = cdatToJson(parameters);



            return true;
        }

        public void Send(out int ErrorCode, out string ErrorText)
        {
            string Message = JsonConvert.SerializeObject(rootClass, Formatting.Indented);

            tcpClient.Send(Message + "&", out ErrorCode, out ErrorText);
        }


        public JObject cdatToJson(CommunicationParameters parameters)
        {
            JObject rootClass = new JObject();
            List<JObject> Object = new List<JObject>();

            if (ncOrTs == "NC")
            {
                JProperty jProperty = null;
                jProperty = new JProperty("Start check", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("Execute command", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("IHandShake01", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("IHandShake02", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("IHandShake03", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("IHandShake04", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("IHandShake05", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("IHandShake06", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("IHandShake07", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("Command code", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("Command parameter", 0);


                rootClass.Add(jProperty);
                jProperty = new JProperty("System alive", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("Automatic mode ready", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("System ready", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("Data valid", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("Check routine result O.K", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("Check routine result n.O.K", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("Self test failed", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("Event log full", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("OHandShake00", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("OHandShake01", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("OHandShake02", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("OHandShake03", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("OHandShake04", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("OHandShake05", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("OHandShake06", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("OHandShake07", 0);
                rootClass.Add(jProperty);

                jProperty = new JProperty("Current check routine ID", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("Current security profile ID", 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty("Last command code", 0);
                rootClass.Add(jProperty);
            }
            else if (ncOrTs == "TS")
            {
                JProperty jProperty = null;
                jProperty = new JProperty(ConstantEnumTS_Input.Command.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.ManFctNo.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.ParaDinit1.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.ParaDinit2.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.ParaDinit3.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.ParaDinit4.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.ParaReal1.ToString(), 0.0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.ParaReal2.ToString(), 0.0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.ParaReal3.ToString(), 0.0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.ParaReal4.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.Para1.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.Para2.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.HandShake00.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.HandShake01.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.HandShake02.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.HandShake03.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.HandShake04.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.HandShake05.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.HandShake06.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.HandShake07.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.StartSingle.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.Continuous.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.CommandOnce.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.BasSet.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Input.WrkSet.ToString(), 0);
                rootClass.Add(jProperty);


                jProperty = new JProperty(ConstantEnumTS_Output.RunStates.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Output.TestplanStates.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Output.ResultStates.ToString(), 0);
                rootClass.Add(jProperty);
                jProperty = new JProperty(ConstantEnumTS_Output.Mode.ToString(), 0);
                rootClass.Add(jProperty);
            }



            for (int i = 0; i < parameters.Objects.Count; i++)
            {
                var objItems = parameters.Objects[i].Items;
                JProperty kewValue = null;
                JObject Objects = new JObject();
                foreach (var objItem in objItems)
                {
                    if (objItem.Array == 1)
                    {
                        if (objItem.Type == "USHORT")
                        {
                            kewValue = new JProperty(objItem.Name, 0);
                        }
                        else if (objItem.Type == "INT")
                        {
                            kewValue = new JProperty(objItem.Name, 0);
                        }
                        else if (objItem.Type == "DOUBLE")
                        {
                            kewValue = new JProperty(objItem.Name, 0);
                        }
                        else if (objItem.Type == "STRING")
                        {
                            kewValue = new JProperty(objItem.Name, "");
                        }
                    }
                    else if (objItem.Array > 1)
                    {
                        if (objItem.Type == "USHORT")
                        {
                            ushort[] ushorts = new ushort[objItem.Array];
                            for (int j = 0; j < ushorts.Length; j++)
                            {
                                ushorts[j] = 0;
                            }
                            kewValue = new JProperty(objItem.Name, ushorts);
                        }
                        else if (objItem.Type == "INT")
                        {
                            int[] ints = new int[objItem.Array];
                            for (int j = 0; j < ints.Length; j++)
                            {
                                ints[j] = 0;
                            }
                            kewValue = new JProperty(objItem.Name, ints);
                        }
                        else if (objItem.Type == "DOUBLE")
                        {
                            double[] doubles = new double[objItem.Array];
                            for (int j = 0; j < doubles.Length; j++)
                            {
                                doubles[j] = 0;
                            }
                            kewValue = new JProperty(objItem.Name, doubles);
                        }
                        else if (objItem.Type == "STRING")
                        {
                            string[] strings = new string[objItem.Array];
                            for (int j = 0; j < strings.Length; j++)
                            {
                                strings[j] = string.Empty;
                            }
                            kewValue = new JProperty(objItem.Name, strings);
                        }
                    }

                    Objects.Add(kewValue);

                }
                Object.Add(Objects);

            }

            for (int i = 0; i < Object.Count(); i++)
            {
                string Objectname = "Object" + parameters.Objects[i].ObjectID.ToString();
                JProperty kewValue = new JProperty(Objectname, Object[i]);
                rootClass.Add(kewValue);
            }

            return rootClass;
        }
    }
    public enum ConstantEnumTS_Input
    {
        Command = 0,
        ManFctNo = 1,
        ParaDinit1 = 2,
        ParaDinit2 = 3,
        ParaDinit3 = 4,
        ParaDinit4 = 5,
        ParaReal1 = 6,
        ParaReal2 = 8,
        ParaReal3 = 10,
        ParaReal4 = 12,
        Para1 = 14,
        Para2 = 15,

        HandShake00 = 16,
        HandShake01 = 17,
        HandShake02 = 18,
        HandShake03 = 19,
        HandShake04 = 20,
        HandShake05 = 21,
        HandShake06 = 22,
        HandShake07 = 23,

        StartSingle = 24,
        Continuous = 25,
        CommandOnce = 26,
        BasSet = 27,
        WrkSet = 28,

    }
    public enum ConstantEnumTS_Output
    {
        RunStates = 29,
        TestplanStates = 30,
        ResultStates = 31,
        Mode = 32,
    }
}
